package jvm

import (
	"bytes"
	"fmt"
	"gitee.com/tietang/terrace-go/v2/lib/tollgate/handler"
	"github.com/shirou/gopsutil/v3/process"
	"os/exec"
	"strconv"
	"strings"
)

type JvmProcess struct {
	handler.ServiceProcess
	Main             string
	ServletContainer string
	Port             int
	Args             []string
}

type JvmProcessHandler struct {
	handler.BaseProcessHandler
}

func (j *JvmProcessHandler) GetProcesses() ([]*handler.ServiceProcess, error) {

	jps, err := GetJpsPath()
	cmd := exec.Command(jps, "-lvm")
	data, err := cmd.Output()
	if err != nil {
		fmt.Println(err.Error())
	}
	cmdLines := bytes.Split(data, []byte("\n"))
	processes := make([]*handler.ServiceProcess, 0)
	for _, cl := range cmdLines {
		jp, err := j.parseLine(cl)
		if err != nil || jp == nil {
			continue
		}

		if jp.ServiceId != "" {
			pss, err := process.NewProcess(int32(jp.Pid))
			if err != nil {
				continue
			}
			jp.Process = pss
			processes = append(processes, jp.Clone())
		}

	}

	return processes, nil
}

func (j *JvmProcessHandler) parseLine(line []byte) (*JvmProcess, error) {
	cmds := bytes.Split(line, []byte(" "))

	jp := &JvmProcess{Args: make([]string, 0)}
	jp.Labels = make(map[string]handler.KV, 0)

	size := len(cmds)
	if size >= 1 {
		pid, err := strconv.Atoi(string(cmds[0]))
		if err != nil {
			return nil, err
		}
		jp.Pid = pid
	}
	if size >= 2 {
		jp.Main = string(cmds[1])
		jp.ServiceId = j.Replace(jp.Main)
	}
	if size > 2 {
		j.parseOutput(jp, cmds)
	}

	jp.ServiceId = j.FileNameToServiceId(jp.Main)
	return jp, nil
}

func (j *JvmProcessHandler) parseOutput(jp *JvmProcess, cmds [][]byte) {
	for i := 2; i < len(cmds); i++ {
		c := cmds[i]
		if strings.Index(string(c), "-D") >= 0 {
			kvs := bytes.Split(c, []byte("="))
			key := kvs[0][2:]
			//TODO 索引溢出问题
			value := kvs[1]
			k := string(bytes.ToLower(key))
			jp.Labels[k] = handler.KV{Key: k, Value: string(value)}
			jp.ParseServiceId()
			jp.ParseHealthCheckUrl()
			jp.ParsePort()
		} else {
			jp.Args = append(jp.Args, string(c))
		}
	}
}
